package com.school.config;

import org.apache.commons.dbcp2.BasicDataSource;

import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
 * 数据库连接池的配置
 * 单例模式 ： 设计模式
 */
public class DbcpConfig {

    /**
     * 单例对象
     */
    private static BasicDataSource instance = null;

    /**
     * 返回一个数据库连接池对象，保证每次获取instance都是同一个
     * 加上同步锁
     * @return  ~
     */
    public static synchronized BasicDataSource getInstance(){
        if (instance == null){
            instance = new BasicDataSource();
            // 从配置文件读取配置参数
            Properties p = new Properties();
            try {
                p.load(DbcpConfig.class.getClassLoader().getResourceAsStream("dbcp.properties"));
                instance.setUsername(p.getProperty("username"));
                instance.setPassword(p.getProperty("password"));
                instance.setUrl(p.getProperty("url"));
                instance.setDriverClassName(p.getProperty("driver"));

                instance.setInitialSize(10);
                instance.setMinIdle(10);
                instance.setMaxIdle(100);
                instance.setMaxTotal(120);
                instance.setMaxWaitMillis(30 * 1000); //关键：超时回收，默认1800000L
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return instance;
    }

    /**
     * 获取连接对象
     * @return  ~
     */
    public static Connection getConnection(){
        try {
            return getInstance().getConnection();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return null;
        }
    }

    /**
     * Statement ： 相当于就是建立数据库一次查询的过程
     * Statement : 适用于数据库的增删改查
     * PrepareStatement ：预编译，效率高，防止SQl的注入
     * CallableStatement ：用于存储过程的查询
     * @param sql   ~
     * @return  ~
     * @throws SQLException ~
     */
    public static PreparedStatement getPreparedStatement(String sql) throws SQLException {
        Connection connection = getConnection();
        if (connection != null){
            return getConnection().prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        }
        return null;
    }

    /**
     * Statement ： 相当于就是建立数据库一次查询的过程
     * Statement : 适用于数据库的增删改查
     * PrepareStatement ：预编译，效率高，防止SQl的注入
     * CallableStatement ：用于存储过程的查询
     * @return  ~
     * @throws SQLException ~
     */
    public static Statement getStatement() throws SQLException {
        Connection connection = getConnection();
        if (connection != null){
            return getConnection().createStatement();
        }
        return null;
    }

    /**
     * Statement ： 相当于就是建立数据库一次查询的过程
     * Statement : 适用于数据库的增删改查
     * PrepareStatement ：预编译，效率高，防止SQl的注入
     * CallableStatement ：用于存储过程的查询
     * @param sql   ~
     * @return  ~
     * @throws SQLException ~
     */
    public static CallableStatement getCallableStatement(String sql) throws SQLException {
        Connection connection = getConnection();
        if (connection != null){
            return getConnection().prepareCall(sql);
        }
        return null;
    }
}
